﻿Option Explicit On
Option Strict On

Imports System
Imports System.Collections

Public Class AliasText

#Region " Private Members "

    Private m_intAlias As Generic.Dictionary(Of String, Object)
    Private m_booleanAlias As Generic.Dictionary(Of String, Object)

#End Region

#Region " Constructors "

    ''' <summary>
    ''' Default Constructor
    ''' </summary>
    ''' <remarks></remarks>
    Public Sub New()
        m_intAlias = InsensitiveDictionary()
        m_booleanAlias = InsensitiveDictionary()
        DefaultAliasLoad()
    End Sub

#End Region

#Region " Public Methods "

    Public Sub AddAlias(ByVal key As String, ByVal [alias] As String, ByVal value As Integer)
        If m_intAlias.ContainsKey(key) Then
            Dim keys As Generic.Dictionary(Of String, Object) = DirectCast(m_intAlias(key), Generic.Dictionary(Of String, Object))
            keys([alias]) = value
        Else
            Dim keys As Generic.Dictionary(Of String, Object) = InsensitiveDictionary()
            keys([alias]) = value
            m_intAlias.Add(key, keys)
        End If
    End Sub

    Public Sub AddAlias(ByVal [alias] As String, ByVal value As Boolean)
        m_booleanAlias([alias]) = value
    End Sub

    Public Sub AddAlias(ByVal key As String, ByVal enumAlias As [Enum])
        SetAliasTypes(key, enumAlias)
    End Sub

    Public Function ContainsBoolean(ByVal key As String) As Boolean
        Return m_booleanAlias.ContainsKey(key)
    End Function

    Public Function ContainsInt(ByVal key As String, ByVal [alias] As String) As Boolean
        Dim result As Boolean = False

        If m_intAlias.ContainsKey(key) Then
            Dim keys As Generic.Dictionary(Of String, Object) = DirectCast(m_intAlias(key), Generic.Dictionary(Of String, Object))
            result = (keys.ContainsKey([alias]))
        End If

        Return result
    End Function

    Public Function GetBoolean(ByVal key As String) As Boolean
        If Not m_booleanAlias.ContainsKey(key) Then
            Throw New ArgumentException("Alias does not exist for text")
        End If

        Return CBool(m_booleanAlias(key))
    End Function

    Public Function GetInt32(ByVal key As String, ByVal [alias] As String) As Integer
        If Not m_intAlias.ContainsKey(key) Then
            Throw New ArgumentException("Alias does not exist for key")
        End If

        Dim keys As Generic.Dictionary(Of String, Object) = DirectCast(m_intAlias(key), Generic.Dictionary(Of String, Object))

        If Not keys.ContainsKey([alias]) Then
            Throw New ArgumentException("Config value does not match a " + "supplied alias")
        End If

        Return CInt(keys([alias]))
    End Function

#End Region

#Region " Private Methods "

    ''' <summary>
    ''' Loads the default alias values.
    ''' </summary>
    Private Sub DefaultAliasLoad()
        AddAlias("true", True)
        AddAlias("false", False)
    End Sub

    ''' <summary>
    ''' Extracts and sets the alias types from an enumeration.
    ''' </summary>
    Private Sub SetAliasTypes(ByVal key As String, ByVal enumAlias As [Enum])
        Dim names As String() = [Enum].GetNames(enumAlias.[GetType]())
        Dim values As Integer() = DirectCast([Enum].GetValues(enumAlias.[GetType]()), Integer())

        For i As Integer = 0 To names.Length - 1
            AddAlias(key, names(i), values(i))
        Next
    End Sub

    ''' <summary>
    ''' Returns a case insensitive dictionary.
    ''' </summary>
    Private Shared Function InsensitiveDictionary() As Generic.Dictionary(Of String, Object)
        Return New Generic.Dictionary(Of String, Object)(StringComparer.OrdinalIgnoreCase)
    End Function

#End Region

End Class
